package com.vinhvt.effiport.algorithm.genetic.bio;

import java.util.Random;


import com.vinhvt.effiport.algorithm.genetic.GAsParameters;
import com.vinhvt.effiport.util.Helper;

public class Individual{
	private double fitness = 0.0;		
	private WeightChromosome chrWeight = new WeightChromosome();	
	private Individual offspring[] = null;	
	
	public Individual() {	
	}
	public Individual(boolean auto) throws InterruptedException {
		if (auto) autogen();	
	}	
			
	private void autogen() throws InterruptedException {
		double po = GAsParameters.PO;	
		int wbl = GAsParameters.WEIGHT_BITS_LENGTH;
		
		for(int i = 0; i < GAsParameters.INDIVIDUAL_SIZE; i++) {											
			boolean[] wbits = Helper.generateBits(po, wbl);
			WeightGene wg = new WeightGene(wbits);
			this.chrWeight.addGene(wg);
		}
		
	}		
	
	/**
	 * Gets the offspring with.
	 * 
	 * @param mom the mom
	 * 
	 * @return the offspring with
	 */
	public Individual[] getOffspringWith(Individual mom) {
		Individual[] result = new Individual[2];
		result[0] = new Individual();
		result[1] = new Individual();
						
		boolean[] dadWeightChromosome = this.chrWeight.getADNStructure();
		boolean[] momWeightChromosome = mom.chrWeight.getADNStructure();
		
		int type = 0;		
		if (type == 0) {// Single crossing over												
			int wpos = new Random().nextInt(dadWeightChromosome.length);
			boolean wtmp;
			for(int i = 0; i < wpos; i++) {
				wtmp = dadWeightChromosome[i];
				dadWeightChromosome[i] = momWeightChromosome[i];
				momWeightChromosome[i] = wtmp;
			}
			
			result[0].setChrWeight(new WeightChromosome(dadWeightChromosome));
			result[1].setChrWeight(new WeightChromosome(momWeightChromosome));
		}			
				
		return result;
	} 
	
	public void mutate() {						
		this.chrWeight.mutate();							
	}
	
	public void setFitness(double fitness) {
		this.fitness = fitness;
	}
	public double getFitness() {
		return fitness;
	}
	
	public void setOffspring(Individual offspring[]) {
		this.offspring = offspring;
	}
	public Individual[] getOffspring() {
		return offspring;
	}	

	


	public void setChrWeight(WeightChromosome chrWeight) {
		this.chrWeight = chrWeight;
	}



	public WeightChromosome getChrWeight() {
		return chrWeight;
	}
	
	@Override
	public String toString() {
		String result = "";
		
		result += "\nIndividual";
		result += "\n\tFitness:" + this.getFitness();					
		result += "\n\tWeight Chromosome:\t\t";
		result += this.chrWeight.toString();
				
		return result;
	}
	
	public int getSize() {
		
		return 0;
	}		
}
